<!DOCTYPE html>



  


<html class="theme-next muse use-motion" lang="zh-CN">
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/hexo/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/hexo/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/hexo/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/hexo/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/hexo/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/hexo/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/hexo/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="开发笔记,">










<meta name="description" content="本来这篇想来聊聊单点登录的相关技术的，但今天突然来了点想法，想聊聊我们在开发中常遇到的一个问题，分页。其实这个问题的解决方案也很成熟了，大家肯定也都接触过，而且我觉得大家再做到分页这部分的时候，基本都是沿用之前写好的逻辑，借这个机会，我来梳理一下分页的整体流程。分页的本质其实是查询，我们系统一般使用的数据库都RDS，关于分页查询，每个RDS类型对应的SQL略有区分，这里我主要说一下sqlserve">
<meta name="keywords" content="开发笔记">
<meta property="og:type" content="article">
<meta property="og:title" content="分页这件小事儿">
<meta property="og:url" content="https://tony_df.coding.net/2019/10/26/分页这件小事儿/index.html">
<meta property="og:site_name" content="Tony&#39;s blog">
<meta property="og:description" content="本来这篇想来聊聊单点登录的相关技术的，但今天突然来了点想法，想聊聊我们在开发中常遇到的一个问题，分页。其实这个问题的解决方案也很成熟了，大家肯定也都接触过，而且我觉得大家再做到分页这部分的时候，基本都是沿用之前写好的逻辑，借这个机会，我来梳理一下分页的整体流程。分页的本质其实是查询，我们系统一般使用的数据库都RDS，关于分页查询，每个RDS类型对应的SQL略有区分，这里我主要说一下sqlserve">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="https://tony_df.coding.net/2019/10/26/分页这件小事儿/1.png">
<meta property="og:image" content="https://tony_df.coding.net/2019/10/26/分页这件小事儿/2.png">
<meta property="og:image" content="https://tony_df.coding.net/2019/10/26/分页这件小事儿/3.png">
<meta property="og:updated_time" content="2019-10-26T02:16:22.259Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="分页这件小事儿">
<meta name="twitter:description" content="本来这篇想来聊聊单点登录的相关技术的，但今天突然来了点想法，想聊聊我们在开发中常遇到的一个问题，分页。其实这个问题的解决方案也很成熟了，大家肯定也都接触过，而且我觉得大家再做到分页这部分的时候，基本都是沿用之前写好的逻辑，借这个机会，我来梳理一下分页的整体流程。分页的本质其实是查询，我们系统一般使用的数据库都RDS，关于分页查询，每个RDS类型对应的SQL略有区分，这里我主要说一下sqlserve">
<meta name="twitter:image" content="https://tony_df.coding.net/2019/10/26/分页这件小事儿/1.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/hexo/',
    scheme: 'Muse',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: 'Tony'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://tony_df.coding.net/2019/10/26/分页这件小事儿/">





  <title>分页这件小事儿 | Tony's blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/hexo/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Tony's blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">学着码代码,学着码人生;</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/hexo/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br>
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/hexo/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br>
            
            Tags
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/hexo/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br>
            
            Archives
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://tony_df.coding.net/hexo/2019/10/26/分页这件小事儿/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Tony">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/hexo/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Tony's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">分页这件小事儿</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2019-10-26T08:33:34+08:00">
                2019-10-26
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>本来这篇想来聊聊单点登录的相关技术的，但今天突然来了点想法，想聊聊我们在开发中常遇到的一个问题，分页。<br>其实这个问题的解决方案也很成熟了，大家肯定也都接触过，而且我觉得大家再做到分页这部分的时候，基本都是沿用之前写好的逻辑，借这个机会，我来梳理一下分页的整体流程。<br>分页的本质其实是查询，我们系统一般使用的数据库都RDS，关于分页查询，每个RDS类型对应的SQL略有区分，这里我主要说一下sqlserver，然后捎带提一下mysql，oracle用的少，就不说了，不过查了下分页的逻辑和sqlserver差不多。<br>接下来我从数据库到系统的呈现，分层次来介绍下分页的实现方式，当然这只是我的思路，为了呈现效果，简化了许多内容。<br>第一步，写好分页查询的类<br>在这一步开始前，我想先说一下分页的sql，在sqlserver里，我看到的最多的分页的写法是这种</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">--先来个实例</span></span><br><span class="line"><span class="keyword">select</span> * <span class="keyword">from</span> (<span class="keyword">select</span> *,ROW_NUMBER() <span class="keyword">over</span> (<span class="keyword">order</span> <span class="keyword">by</span> <span class="keyword">id</span>)<span class="keyword">AS</span> <span class="keyword">RowId</span> <span class="keyword">from</span> WxOauths) <span class="keyword">as</span> b <span class="keyword">where</span>  <span class="keyword">RowId</span> <span class="keyword">between</span> <span class="number">1</span> <span class="keyword">and</span> <span class="number">10</span></span><br></pre></td></tr></table></figure>

<p>看下执行结果<br><img src="1.png" alt="分页实例"><br>那么我们看到这个例子里，可以提出来的部分，整理成类似公式的东西，然后根据公式，我们就可以写出一个通用的类，首先，从左往右，我们看到第一个我们自己定义的实参是id这个属性，就是需要排序的字段，我们需要这样一个参数，让rds帮助我们完成分页，那么这个id就可以定义成一个形参，再往后看到第二个实参是WxOauths，这是个表名，当然这里也可以是一个检索结果，所以这里使我们第二个设置形参的地方，再往后我们看到between的区间值，设定的也是固定的实参，所以这里分别是第三，四个形参，到这里，分页的sql原理我们差不多搞清了，可以去写代码了~</p>
<figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">string</span> <span class="title">CreatePagingSql</span>(<span class="params"><span class="keyword">int</span> _pageSize, <span class="keyword">int</span> _pageIndex, <span class="keyword">string</span> _safeSql, <span class="keyword">string</span> _orderField</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (_pageIndex &lt; <span class="number">1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        _pageIndex = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//拼接SQL字符串，加上ROW_NUMBER函数进行分页</span></span><br><span class="line">    StringBuilder newSafeSql = <span class="keyword">new</span> StringBuilder();</span><br><span class="line">    newSafeSql.AppendFormat(<span class="string">"SELECT ROW_NUMBER() OVER(ORDER BY &#123;0&#125;) as row_number,"</span>, _orderField);</span><br><span class="line">    newSafeSql.Append(_safeSql.Substring(_safeSql.ToUpper().IndexOf(<span class="string">"SELECT"</span>) + <span class="number">6</span>));</span><br><span class="line">    <span class="comment">//拼接成最终的SQL语句</span></span><br><span class="line">    StringBuilder sbSql = <span class="keyword">new</span> StringBuilder();</span><br><span class="line">    sbSql.Append(<span class="string">"SELECT * FROM ("</span>);</span><br><span class="line">    sbSql.Append(newSafeSql.ToString());</span><br><span class="line">    sbSql.Append(<span class="string">") AS T"</span>);</span><br><span class="line">    sbSql.AppendFormat(<span class="string">" WHERE row_number between &#123;0&#125; and &#123;1&#125;"</span>, ((_pageIndex - <span class="number">1</span>) * _pageSize) + <span class="number">1</span>, _pageIndex * _pageSize);</span><br><span class="line">    <span class="keyword">return</span> sbSql.ToString();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这段代码非常简单，就是简单地把我们前面写的那个实例，拆分开，然后根据我们找到的四个需要传入实参的地方，用形参来拼接好，组成最终的查询语句。<br>在实际当中，我们往往还需要一个汇总的值total，来告诉前端总共的条数，我们还是看到上面那个实例，统计总数其实就是统计表或者查询结果的条数，也就是第二个形参，所以这段代码非常简单</p>
<figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">string</span> <span class="title">CreateCountingSql</span>(<span class="params"><span class="keyword">string</span> _safeSql</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">string</span>.Format(<span class="string">" SELECT COUNT(1) AS RecordCount FROM (&#123;0&#125;) AS T "</span>, _safeSql);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>结合上面的方法，我们写一个总的分页调用方法，得到分页结果和总条数；</p>
<figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> DataSet <span class="title">GetPageList</span>(<span class="params"><span class="keyword">int</span> pageSize, <span class="keyword">int</span> pageIndex, <span class="keyword">string</span> strWhere, <span class="keyword">string</span> filedOrder, <span class="keyword">out</span> <span class="keyword">int</span> recordCount, <span class="keyword">string</span> selected</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    StringBuilder strSql = <span class="keyword">new</span> StringBuilder();</span><br><span class="line">    strSql.Append(<span class="string">"select "</span>);</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">string</span>.IsNullOrEmpty(selected))</span><br><span class="line">    &#123;</span><br><span class="line">        strSql.Append(<span class="string">"*"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        strSql.Append(selected);</span><br><span class="line">    &#125;</span><br><span class="line">    strSql.Append(<span class="string">" FROM "</span> + datatable);</span><br><span class="line">    <span class="keyword">if</span> (strWhere.Trim() != <span class="string">""</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        strSql.Append(<span class="string">" where "</span> + strWhere);</span><br><span class="line">    &#125;</span><br><span class="line">    recordCount = Convert.ToInt32(DbHelperSQL.GetSingle(PagingHelper.CreateCountingSql(strSql.ToString())));</span><br><span class="line">    <span class="keyword">if</span> (pageSize &gt; <span class="number">0</span> &amp;&amp; pageIndex &gt; <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> DbHelperSQL.Query(PagingHelper.CreatePagingSql(pageSize, pageIndex, strSql.ToString(), filedOrder));</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        <span class="keyword">return</span> DbHelperSQL.Query(strSql.ToString() + <span class="string">" order by "</span> + filedOrder);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>注意，这里用到的关键技术其实还是拼接，但是由于是sql，所以该方法的上层应该还有一个方法来处理sql条件，避免sql注入。因为是演示，这一步我就不写了，提供个思路吧，过滤sql条件的话其实有好多方法，一是我们引用反射和SqlParameter的类来对完成sql的赋值操作，这样可以很好的避免注入风险，缺点就是，时间复杂度比较高，我比较常用的方式是在参数传入的模型层，通过添加DataAnnotations命名空间，通过模型验证的方式完成参数的正确性验证，如果你用过诸如EntityFramework这样的orm框架，对这点应该很熟悉。<br>接下来我们到我们的实际业务层代码里去调用了</p>
<figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> ActionResult <span class="title">GetList</span>(<span class="params"><span class="keyword">int</span> pageindex=<span class="number">1</span>,<span class="keyword">int</span> pagesize=<span class="number">10</span></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Response resp = <span class="keyword">new</span> Response();</span><br><span class="line">    <span class="keyword">try</span></span><br><span class="line">    &#123;</span><br><span class="line">        BLL.Member bll = <span class="keyword">new</span> BLL.Member();</span><br><span class="line">        <span class="keyword">int</span> total = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">var</span> ds = bll.GetPageList(pagesize, pageindex, <span class="string">""</span>, <span class="string">"Created_at desc"</span>, <span class="keyword">out</span> total,<span class="string">"MemberID,Name,School,Mobile,ICNo,Province"</span>);</span><br><span class="line">        <span class="keyword">if</span> (total &gt; <span class="number">0</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            IList&lt;Models.ResponseMember&gt; list = Common.ModelConvertHelper&lt;Models.ResponseMember&gt;.ConvertToModel(ds.Tables[<span class="number">0</span>]);</span><br><span class="line">            resp.code = <span class="number">1</span>;</span><br><span class="line">            resp.data = <span class="keyword">new</span> &#123; total, items = list &#125;;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span>(Exception ex)</span><br><span class="line">    &#123;</span><br><span class="line">        resp.code = <span class="number">-1</span>;</span><br><span class="line">        resp.message = <span class="string">"error:"</span> + ex.Message;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Json(resp, JsonRequestBehavior.AllowGet);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>至此，后端的分页处理流程就完成了，看下效果<br><img src="2.png" alt="分页请求"><br>到这里，我想多说两点，关于最开始我们提到的分页方法，到sqlserver2012以后，微软提供了一种新的分页方式，并且推荐sql2012以后的版本使用该方式来进行分页查询，目前我们最新的项目里，底层的分页写法都已经改成了这种，这里分享一下</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> * <span class="keyword">from</span> WxOauths  <span class="keyword">order</span> <span class="keyword">by</span> <span class="keyword">id</span> <span class="keyword">offset</span> <span class="number">0</span> <span class="keyword">rows</span> <span class="keyword">fetch</span> <span class="keyword">next</span> <span class="number">10</span> <span class="keyword">rows</span> <span class="keyword">only</span></span><br></pre></td></tr></table></figure>

<p><img src="3.png" alt="新分页方式"><br>可以看到，新的方式在阅读方式上更加友好，其中offset是偏移量，fetch next是要取的条数，我们依然可以根据前面提到的方式，把需要的四个形参提取出来，整理成公式，这个我就不多说了。<br>再聊一下mysql的分页语法，额…本来想在这在举举例子，鉴于最近用的不多，分享个链接吧，里面有mysql的各种分页写法和效率对比，传送门:<a href="https://blog.csdn.net/bandaoyu/article/details/89844673" target="_blank" rel="noopener">https://blog.csdn.net/bandaoyu/article/details/89844673</a></p>
<p>好了，如果你的项目是前后端分离的，完成上面的步骤，就可以了，呈现的部分，则交由前端的同事来完成，根据经验，这已经足够了。<br>那么如果我们是做的mvc或者需要自己来写分页页面的系统，我们需要自己来写前端的逻辑，我这里也分享下我的做法。<br>首先，我还不会用流行的mvvm框架，如vue、angular，所以我这里分享的还是传统的借助jQuery的形式来完成分页的方法，</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取列表</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getPage</span>(<span class="params">params</span>)</span>&#123;</span><br><span class="line">    $.getJson(params.url,params.data,<span class="function"><span class="keyword">function</span>(<span class="params">json</span>)</span>&#123;</span><br><span class="line">        chargeTpl(params.tpl, params.view, json.data.items, <span class="literal">true</span>);</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//填充模板</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">chargeTpl</span>(<span class="params">tplid, viewid, checkbarParams, append</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (tplid &amp;&amp; viewid) &#123;</span><br><span class="line">        <span class="keyword">var</span> tpl = <span class="built_in">document</span>.getElementById(tplid).innerHTML, view = <span class="built_in">document</span>.getElementById(viewid);</span><br><span class="line">        layui.use(<span class="string">'laytpl'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">            <span class="keyword">var</span> laytpl = layui.laytpl;</span><br><span class="line">            laytpl(tpl).render(checkbarParams, <span class="function"><span class="keyword">function</span> (<span class="params">html</span>) </span>&#123;</span><br><span class="line">                <span class="keyword">if</span> (append)</span><br><span class="line">                    view.innerHTML += html;</span><br><span class="line">                <span class="keyword">else</span></span><br><span class="line">                    view.innerHTML = html;</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>说明一下，chargeTpl是我封装的一个填充模板的方法，用到了layui里的模板组件，实际使用的时候，这里是根据逻辑来完成的，params是一个数组，个人觉得在传入多个参数的时候，已数组形式比罗列多个参数要好很多，起码参数顺序不用固定了。<br>如果是手机端，需要上拉或者下拉加载，那么我们还要有一个加载分页的方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">loadMore</span>(<span class="params">params</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (totalRows &lt;= (params.pageIndex - <span class="number">1</span>) * params.pageSize) &#123;</span><br><span class="line">        layer.msg(<span class="string">"没有更多了"</span>);</span><br><span class="line">        $(<span class="string">"#loadMore"</span>).hide();<span class="comment">//加载完成后，隐藏加载模块</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        getPage(params);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>代码很简单，意思是有一个加载更多的区域，当我们滑动到底部或者顶部的时候，会触发loadMore事件，完成分页请求，当全部加载完成后，将绑定该事件的模块隐藏<br>至此，前端分页的核心逻辑就全部完成了。<br>在此，推荐一个前端框架，相信很多人都已经非常熟悉了，layui，无论是在GitHub还是Gitee上layui的star数量非常多，是非常受欢迎的前端集成开发框架，我目前多个B/S的项目几乎都或多或少的会用到里面的组件，非常方便，也很节约时间，再此强烈安利一下<a href="https://www.layui.com/doc/" target="_blank" rel="noopener">https://www.layui.com/doc/</a>。<br>好了,这件小事儿，说完了，下篇再见~</p>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/hexo/tags/开发笔记/" rel="tag"># 开发笔记</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/hexo/2019/10/23/欲买桂花同载酒，终不似，少年游/" rel="next" title="欲买桂花同载酒，终不似，少年游">
                <i class="fa fa-chevron-left"></i> 欲买桂花同载酒，终不似，少年游
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/hexo/2019/11/02/实现一个简单的单点登录（用-net-core实现）/" rel="prev" title="实现一个简单的单点登录（用asp.net core 3.0实现）">
                实现一个简单的单点登录（用asp.net core 3.0实现） <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
        <!-- Go to www.addthis.com/dashboard to customize your tools -->
<div class="addthis_inline_share_toolbox">
  <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5bbb2338b87602f0" async="async"></script>
</div>

      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="lv-container" data-id="city" data-uid="MTAyMC8zOTA1My8xNTU4MA"></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">Tony</p>
              <p class="site-description motion-element" itemprop="description">学习总结</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/hexo/archives/">
              
                  <span class="site-state-item-count">58</span>
                  <span class="site-state-item-name">posts</span>
                </a>
              </div>
            

            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/hexo/tags/index.html">
                  <span class="site-state-item-count">7</span>
                  <span class="site-state-item-name">tags</span>
                </a>
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Tony</span>

  
</div>


  <div class="powered-by">Powered by <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a></div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">Theme &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Muse</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/hexo/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/hexo/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/hexo/js/src/motion.js?v=5.1.4"></script>



  
  

  
  <script type="text/javascript" src="/hexo/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/hexo/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/hexo/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
  












  





  

  

  

  
  

  

  

  

</body>
</html>
